home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // Scn15p3: AI Scenario Script for scenario 15 player 3
- //==============================================================================
- /*
- AI owner: Mike Kidd
- Scenario owner: Jeff Brown
-
- Overview:
- The player's task is to protect the relic sword, build up, and then find
- a way to deliver it to the sleeping colossus in the fortified enemy town.
-
- The CP starts in the second age, maintaining a reserve of spearmen. Starting
- at nextAttackTime (adjusted for the time spent in cinematics, i.e. "startTime")
- and at attackInterval intervals after that, it sends an army of attackSize units.
- AttackSize is multiplied by attackSizeMultiplier each time, to a max of maxAttackSize.
-
- In the third age, the CP maintains a reserve of chariot archers in addition to the
- spearmen, and adds anubites. The attack groups will contain one anubite, a few
- CAs, and a majority of spearmen.
-
- In the fourth age, the CP adds scorpionmen and avengers. The attack groups will have
- a small number of myth units, several CAs, and the balance filled in with spearmen.
-
- Unit line and armory upgrades are added through the ages.
-
- The CP will invoke Vision somewhere in the general area of the player's TC.
- (Vector +/- 50m in X and Z.) The CP can use Serpents and Ancestors as needed,
- generally near an army or near the city gates. Tornado is reserved for trigger effects.
-
- This script receives outerWall() and innerWall() alerts when the walls are
- endangered, and it reacts by drafting an ad-hoc army for defense.
-
- Difficulty: Implemented 7/15
-
- 8/20/2002: Reduced gather range on defend plan to relieve congestion at barracks.
-
- 9/05/2002: Reduced strength of defend plans on all levels, other minor difficulty adjustments
-
- */
- //==============================================================================
-
-
- include "scn lib.xs";
-
-
- // *****************************************************************************
- //
- // Globals
- //
- // *****************************************************************************
-
- // Attack routes
- int routeEast = -1;
- int routeWest = -1;
-
-
- // Army control
- int lastAttackPlan = -1; // Used to find "my army" for god power position info
- int defendPlan = -1;
- int nextAttackTime = 300000; // Will be adjusted for the wakeup time
- int attackInterval = 240000; // Attack every 4 minutes
- float attackSize = 3.0;
- float attackMultiplier = 1.2;
- int maxAttackSize = 10;
-
- int spearmanMaintain = -1; // Plan to maintain spearman pop
- int chariotArcherMaintain = -1;
- int anubiteMaintain = -1;
- int scorpionManMaintain = -1;
- int avengerMaintain = -1;
-
- int spearmanQty = 4; // Quantity to maintain
- int spearmanDelay = 30; // Interval between training units
- int chariotQty = 4; // Quantity to maintain
- int chariotDelay = 30; // Interval between training units
- int anubiteQty = 1; // Quantity to maintain
- int anubiteDelay = 90; // Interval between training units
- int scorpionQty = 1; // Quantity to maintain
- int scorpionDelay = 90; // Interval between training units
- int avengerQty = 1; // Quantity to maintain
- int avengerDelay = 90; // Interval between training units
-
-
-
- // Cinematic blocks
- const string cbInnerGate = "1450";
- const string cbOuterGate = "1451";
- const string cbEastRoute1 = "1452";
- const string cbEastRoute2 = "1453";
- const string cbEastRoute3 = "1454";
- const string cbEastRoute4 = "1459";
- const string cbWestRoute1 = "1455";
- const string cbWestRoute2 = "1456";
- const string cbWestRoute3 = "1458";
- //const string cbSettlementNorth = "1457";
- const string cbSettlementCenter = "1460";
- //const string cbSettlementSouth = "1461";
- const string cbGuardian = "1462";
- const string cbBarracksGather = "1463";
- const string cbTempleGather = "1464";
- const string cbMigdolGather = "1465";
- const string cbCourtyard = "3263"; // Front courtyard inside outer gates
- const string cbDefendPoint = "3259"; // Center of defend zone
-
-
- // Misc.
- int age3Time = 1200000; // 20 min
- int age4Time = 36000000; // 10 hours!
- int startTime = -1; // Time of the wakeup() function
- int useVisionTime = -1; // Time to use vision god power
-
-
- // *****************************************************************************
- //
- // FUNCTIONS
- //
- // *****************************************************************************
-
-
- // Called by trigger when the cinematics are done
- void wakeup(int parm=-1)
- {
- static bool alreadyRun = false;
- aiEcho("Wakeup running at "+timeString());
- if (alreadyRun == true)
- return;
- alreadyRun = true;
-
- startTime = xsGetTime();
- age3Time = age3Time + startTime; // Adjust for delay in wakeup.
- xsEnableRule("goToAge3");
- age4Time = age4Time + startTime;
- nextAttackTime = nextAttackTime + startTime;
- useVisionTime = startTime+30000+aiRandInt(120)*1000; // Use vision 30-150 seconds from now
-
- xsEnableRule("useVision");
- xsEnableRule("scout");
- xsEnableRule("getAge2UnitUpgrades");
- xsEnableRule("getAge2ArmoryUpgrades");
- xsEnableRule("attackGenerator");
- spearmanMaintain = maintainUnit(cUnitTypeSpearman, spearmanQty, kbGetBlockPosition(cbBarracksGather), spearmanDelay);
- chariotArcherMaintain = maintainUnit(cUnitTypeChariotArcher, chariotQty, kbGetBlockPosition(cbMigdolGather), chariotDelay);
- anubiteMaintain = maintainUnit(cUnitTypeAnubite, anubiteQty, kbGetBlockPosition(cbTempleGather), anubiteDelay) ;
- // Maintain myth units
- scorpionManMaintain = maintainUnit(cUnitTypeScorpionMan, scorpionQty, kbGetBlockPosition(cbTempleGather), scorpionDelay);
- avengerMaintain = maintainUnit(cUnitTypeAvenger, avengerQty, kbGetBlockPosition(cbTempleGather), avengerDelay);
-
-
- // Init low-priority defend plan
- defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);
- if (defendPlan >= 0)
- {
- aiPlanAddUnitType(defendPlan, cUnitTypeMilitary, 0, 200, 200); // All unassigned mil units
- aiPlanSetDesiredPriority(defendPlan, 10); // Way low, below scouting and attack
- aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefendPoint));
- aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 100);
- aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
- aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 20.0);
- aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbDefendPoint));
- aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
-
- aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
- aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
-
- aiEcho("Creating defend plan");
- aiPlanSetActive(defendPlan);
- }
- }
-
- /*
- // Called via trigger when the outer wall is in danger of falling...AI should rally nearby units
- void outerWall(int parm=-1)
- {
- int count=0;
- int attackID=aiPlanCreate("Outer Wall Attack", cPlanAttack);
-
- // Rally units to defend...all units within 40 meters, to a maximum of 10 units
- aiEcho("Outer wall emergency.");
- count = getUnassignedUnitCount(kbGetBlockPosition(cbOuterGate), 40.0, 2, cUnitTypeMilitary);
- if (count > 10)
- count = 10;
-
- if (attackID < 0)
- return;
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- return;
-
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbTempleGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 25.0);
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbTempleGather));
-
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, count, count );
-
- aiEcho("Responding with "+count+" units.");
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbOuterGate));
- aiPlanSetRequiresAllNeedUnits(attackID, true);
- aiPlanSetActive(attackID);
- }
-
- // Called via trigger when the inner wall is in danger of falling...AI should throw everything at it
- void innerWall(int parm=-1)
- {
- // Rally units to defend...anywhere on the map, up to 30 units
-
- int count=0;
- int attackID=aiPlanCreate("Inner Wall Attack", cPlanAttack);
-
- aiEcho("Inner wall emergency.");
- count = getUnassignedUnitCount(kbGetBlockPosition(cbInnerGate), 200.0, 2, cUnitTypeMilitary);
- if (count > 30)
- count = 30;
-
- if (attackID < 0)
- return;
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- return;
-
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbTempleGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 25.0);
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbTempleGather));
-
-
-
- aiPlanAddUnitType(attackID, cUnitTypeMilitary, 1, count, count );
-
- aiEcho("Responding with "+count+" units.");
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbInnerGate));
- aiPlanSetRequiresAllNeedUnits(attackID, true);
- aiPlanSetActive(attackID);
- }
- */
-
-
- void age2EventHandler(int bogus=-1)
- {
- //xsEnableRule("useSerpents");
-
- }
-
-
-
- void age3EventHandler(int bogus=-1)
- {
- xsEnableRule("useAncestors");
- xsEnableRule("goToAge4");
- xsEnableRule("getAge3UnitUpgrades");
- xsEnableRule("getAge3ArmoryUpgrades");
-
- }
-
-
-
- void age4EventHandler(int bogus=-1)
- {
- //DO NOT USE TORNADO. Rerserved for trigger use!
- xsEnableRule("getAge4UnitUpgrades");
- xsEnableRule("getAge4ArmoryUpgrades");
- }
-
-
-
-
- void attack(int size=0)
- {
-
- int min=0;
- int sec=0;
-
- int attackID=aiPlanCreate("Attack at "+timeString(), cPlanAttack);
- if (attackID < 0)
- return;
-
- if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
- return;
-
- if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 2, true) == false)
- return;
-
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
-
- if (aiRandInt(2) == 0)
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeWest);
- else
- aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeEast);
-
-
- aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbTempleGather));
- aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 25.0);
-
- switch(kbGetAge())
- {
- case cAge2:
- { // All spearmen
- aiPlanAddUnitType(attackID, cUnitTypeSpearman, 0, size, size );
- break;
- }
- case cAge3:
- { // 70% spear, 30% CA, plus one myth unit
- aiPlanAddUnitType(attackID, cUnitTypeSpearman, 0, ((7*size+5))/10, ((7*size+5))/10 );
- aiPlanAddUnitType(attackID, cUnitTypeChariotArcher, 0, ((3*size+5))/10, ((3*size+5))/10 );
- aiPlanAddUnitType(attackID, cUnitTypeMythUnit, 0, 1, 1);
-
- break;
- }
- case cAge4:
- { // 50% spear, 30% CA, 20% myth
- aiPlanAddUnitType(attackID, cUnitTypeSpearman, 0, size/2, size/2 );
- aiPlanAddUnitType(attackID, cUnitTypeChariotArcher, 0, (3*size)/10, (3*size)/10 );
- aiPlanAddUnitType(attackID, cUnitTypeMythUnit, 0, (size+2)/5, (size+2)/5 );
- break;
- }
- }
-
- aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbTempleGather));
- aiPlanSetRequiresAllNeedUnits(attackID, true);
- aiPlanSetActive(attackID);
- aiEcho("Activating attack plan "+attackID+" with appx "+size+" units.");
- lastAttackPlan = attackID; // update the global var
- }
-
-
-
-
-
- void main()
- {
- aiEcho("Starting Scn15p3.xs");
-
-
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- aiRandSetSeed();
- kbSetTownLocation(kbGetBlockPosition(cbTempleGather));
-
- aiSetAttackResponseDistance(20.0);
-
- // Kill escrows
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0);
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0);
- kbEscrowAllocateCurrentResources();
-
-
- aiSetAgeEventHandler(cAge2, "age2EventHandler");
- aiSetAgeEventHandler(cAge3, "age3EventHandler");
- aiSetAgeEventHandler(cAge4, "age4EventHandler");
-
- routeWest = attackRoute("West Attack Route",cbInnerGate, cbWestRoute1,cbWestRoute2);
- routeEast = attackRoute("East Attack Route",cbInnerGate, cbEastRoute1, cbEastRoute2, cbEastRoute3);
-
- aiEcho("Difficulty = "+aiGetWorldDifficulty());
- switch (aiGetWorldDifficulty())
- { // Note: Difficulty 0 takes the defaults
- case 1:
- {
- spearmanQty = 10;
- spearmanDelay = 30;
- chariotQty = 6;
- chariotDelay = 30;
- anubiteQty = 2;
- anubiteDelay = 90;
- scorpionQty = 2;
- scorpionDelay = 90;
- avengerQty = 2;
- avengerDelay = 90;
- nextAttackTime = 300000;
- attackInterval = 240000;
- attackSize = 3.0;
- attackMultiplier = 1.2;
- maxAttackSize = 12;
- age3Time = 20*60*1000;
- age4Time = 40*60*1000;
- break;
- }
- case 2:
- {
- spearmanQty = 20;
- spearmanDelay = 30;
- chariotQty = 12;
- chariotDelay = 30;
- anubiteQty = 3;
- scorpionQty = 3;
- avengerQty = 3;
- scorpionDelay = 60;
- avengerDelay = 60;
- anubiteDelay = 60;
- nextAttackTime = 180000;
- attackInterval = 180000;
- attackSize = 5.0;
- attackMultiplier = 1.2;
- maxAttackSize = 25;
- age3Time = 15*60*1000;
- age4Time = 25*60*1000;
- break;
- }
- case 3:
- {
- spearmanQty = 30;
- spearmanDelay = 20;
- chariotQty = 20;
- chariotDelay = 20;
- anubiteQty = 5;
- scorpionQty = 5;
- avengerQty = 5;
- scorpionDelay = 40;
- avengerDelay = 40;
- anubiteDelay = 40;
- nextAttackTime = 30000;
- attackInterval = 180000;
- attackSize = 6.0;
- attackMultiplier = 1.3;
- maxAttackSize = 35;
- age3Time = 10*60*1000;
- age4Time = 20*60*1000;
- break;
- }
- }
- }
-
-
-
-
-
-
-
- // *****************************************************************************
- //
- // RULES
- //
- // *****************************************************************************
-
- rule scout
- inactive
- minInterval 5
- {
- // just set up an explore plan
- int exploreID = aiPlanCreate("Explore", cPlanExplore);
- if(exploreID >= 0)
- {
- aiPlanSetVariableFloat( exploreID, cExplorePlanLOSMultiplier, 0, 4.0 );
- aiPlanAddUnitType(exploreID, cUnitTypeSpearman, 1, 1, 1);
- aiPlanSetActive(exploreID);
- }
- xsDisableSelf();
- }
-
-
- rule goToAge3
- inactive
- mininterval 20
- {
- if ( xsGetTime() < age3Time )
- return;
- researchTech(cTechAge3Nephthys);
- xsDisableSelf();
- }
-
-
- rule goToAge4
- inactive
- mininterval 20
- {
- if ( xsGetTime() < age4Time )
- return;
- researchTech(cTechAge4Horus);
- xsDisableSelf();
- }
-
-
-
- rule getAge2UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (startTime + startTime + age3Time)/3 )
- return; // Wait till 1/3 to age3
- researchTech(cTechMediumAxemen);
- researchTech(cTechMediumSlingers);
- researchTech(cTechMediumSpearmen);
- xsDisableSelf();
- }
-
- rule getAge2ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (startTime + age3Time + age3Time)/3 )
- return; // Wait till 2/3 to age3
- aiEcho("Getting age 2 armory upgrades");
- researchTech(cTechCopperWeapons);
- researchTech(cTechCopperMail);
- researchTech(cTechCopperShields);
- xsDisableSelf();
- }
-
- rule getAge3UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+180000) )
- return;
- researchTech(cTechHeavyAxemen);
- researchTech(cTechHeavySlingers);
- researchTech(cTechHeavySpearmen);
- researchTech(cTechHeavyChariots);
- xsDisableSelf();
- }
-
- rule getAge3ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age3Time+300000) )
- return;
- researchTech(cTechBronzeWeapons);
- researchTech(cTechBronzeMail);
- researchTech(cTechBronzeShields);
- xsDisableSelf();
- }
-
- rule getAge4UnitUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age4Time+180000) )
- return;
- researchTech(cTechChampionAxemen);
- researchTech(cTechChampionSlingers);
- researchTech(cTechChampionSpearmen);
- researchTech(cTechChampionChariots);
- xsDisableSelf();
- }
-
- rule getAge4ArmoryUpgrades
- inactive
- minInterval 20
- {
- if ( xsGetTime() < (age4Time+300000) )
- return;
- researchTech(cTechIronWeapons);
- researchTech(cTechIronMail);
- researchTech(cTechIronShields);
- xsDisableSelf();
- }
-
-
-
- rule attackGenerator
- minInterval 10
- inactive
- {
- //aiEcho("attack check running, next time is "+nextAttackTime);
- if ( xsGetTime() < nextAttackTime )
- return;
-
- attack(attackSize);
- nextAttackTime = xsGetTime() + attackInterval;
- attackSize = attackSize * attackMultiplier;
- if (attackSize > maxAttackSize)
- attackSize = maxAttackSize;
- aiEcho("Next attack size will be "+attackSize+".");
- }
-
-
-
-
-
-
- rule useVision // When it's time, cast vision at P1 TC +/- 50 meters
- minInterval 5
- inactive
- {
- if ( xsGetTime() < useVisionTime )
- return;
-
- vector aimHere = vector(-1,-1,-1);
- int dx = -50;
- int dz = -50;
- dx = dx+aiRandInt(100);
- dz = dz+aiRandInt(100); // aim at middle TC +/- 50 meters in X and Z
- aimHere = kbGetBlockPosition(cbSettlementCenter);
- aimHere = xsVectorSetX(aimHere, xsVectorGetX(aimHere)+dx);
- aimHere = xsVectorSetZ(aimHere, xsVectorGetZ(aimHere)+dz);
-
- if (aiCastGodPowerAtPosition(cTechVision, aimHere) == true)
- {
- aiEcho("Vision has been used at "+aimHere);
- xsDisableSelf();
- }
- }
-
-
- rule useSerpents
- minInterval 5
- inactive
- {
- // look for a group of 5 enemy units, at the inner gate or at my main army's location
- int targetUnit = -1;
-
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useSerpents1");
- if ( configQuery(tempQuery, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbInnerGate), true, 75) == false)
- return;
- }
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 5)
- {
- if (lastAttackPlan < 0)
- return;
- vector pVec = aiPlanGetLocation(lastAttackPlan);
- if (xsVectorGetX(pVec)>=0)
- {
- static int tempQuery2 = -1;
- if (tempQuery2 < 0)
- { // Doesn't exist, set it up
- tempQuery2 = kbUnitQueryCreate("useSerpents2");
- if ( configQuery(tempQuery2, cUnitTypeMilitary, -1, cUnitStateAlive, 1, pVec, true, 50) == false)
- return;
- }
- else
- kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
- kbUnitQueryResetResults(tempQuery2);
- targetCount = kbUnitQueryExecute(tempQuery2);
- if (targetCount < 5)
- return;
- else
- targetUnit = kbUnitQueryGetResult(tempQuery2, 0); // grab first unit
- }
- }
- else
- targetUnit = kbUnitQueryGetResult(tempQuery, targetCount/2); // grab middle unit
-
-
- aiEcho("Using Plague of Serpents at "+kbUnitGetPosition(targetUnit));
- if ( aiCastGodPowerAtPosition(cTechSerpents, kbUnitGetPosition(targetUnit)) == true)
- xsDisableSelf();
- else
- aiEcho("Serpents failed at "+kbUnitGetPosition(targetUnit));
- }
-
-
- rule useAncestors // Same logic as Serpents, look for enemy military units
- minInterval 5
- inactive
- {
- // look for a group of 5 enemy units, at the Migdol location or at my main army's location
- int targetUnit = -1;
-
- static int tempQuery = -1;
- if (tempQuery < 0)
- { // Doesn't exist, set it up
- tempQuery = kbUnitQueryCreate("useAncestors1");
- if ( configQuery(tempQuery, cUnitTypeUnit, -1, cUnitStateAlive, 1, kbGetBlockPosition(cbInnerGate), true, 75) == false)
- return;
- }
- kbUnitQueryResetResults(tempQuery);
- int targetCount = kbUnitQueryExecute(tempQuery);
-
- if (targetCount < 5)
- {
- vector pVec = aiPlanGetLocation(lastAttackPlan);
- if (xsVectorGetX(pVec)>=0)
- {
- static int tempQuery2 = -1;
- if (tempQuery2 < 0)
- { // Doesn't exist, set it up
- tempQuery2 = kbUnitQueryCreate("useAncestors2");
- if ( configQuery(tempQuery2, cUnitTypeMilitary, -1, cUnitStateAlive, 1, pVec, true, 50) == false)
- return;
- }
- else
- kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
- kbUnitQueryResetResults(tempQuery2);
- targetCount = kbUnitQueryExecute(tempQuery2);
- if (targetCount < 5)
- return;
- else
- targetUnit = kbUnitQueryGetResult(tempQuery2, 0); // grab first unit
- }
- else
- return; // No army to check
- }
- else//SkeletonPower//PharaohRespawnCityoftheDead
- targetUnit = kbUnitQueryGetResult(tempQuery, targetCount/2); // grab middle unit
-
-
- aiEcho("Using Ancestors");
- if ( aiCastGodPowerAtPosition(cTechSkeletonPower, kbUnitGetPosition(targetUnit)) == true)
- xsDisableSelf();
- else
- aiEcho("Ancestors failed at "+kbUnitGetPosition(targetUnit));
- }
-
-
-